﻿using System;
using System.Linq;

namespace StreetPacMan.Server.Rules
{
    internal interface IPacManGhostCollisionRule
    {
        void DoSideEffects(Player pacman, Player ghost, PacManDataContext dataContext);
    }

    public class EatTheVaulnrablePlayerRule : IPacManGhostCollisionRule
    {
        public void DoSideEffects(Player pacman, Player ghost, PacManDataContext dataContext)
        {
            if(pacman.Game.StateEnum == GameState.SuperPacMan)
            {
                ghost.StateEnum = PlayerState.JoinedEatenNotPlaying;
                dataContext.AddGameEvent(EventType.PacManAteGhost, string.Format("PacMan {0} ate ghost {1}", pacman.Name, ghost.Name),pacman.Id,pacman.GameId);
            }
            else
            {
                pacman.StateEnum = PlayerState.JoinedEatenNotPlaying;
                dataContext.AddGameEvent(EventType.GhostAtePacMan, string.Format("Ghost {0} ate PacMan {1}", ghost.Name, pacman.Name), ghost.Id, ghost.GameId);
            
                pacman.Game.StateEnum = GameState.WatingForNextPacManToStart;
                pacman.Game.StateChangeTime = DateTime.Now;
            }
        }
    }

    public class GameOverIfGhostAteLastPacManRule : IPacManGhostCollisionRule
    {
        public void DoSideEffects(Player pacman, Player ghost, PacManDataContext dataContext)
        {
            if (pacman.Game.StateEnum == GameState.SuperPacMan)
            {
                return;
            }

            var pacMenWhichWereNotKilledYet =
                dataContext
                    .Players
                    .Where(x => x.GameId == pacman.GameId)
                    .Where(x => x.Role == (int)PlayerRole.PacMan)
                    .Where(x => x.State != (int)PlayerState.JoinedEatenNotPlaying)
                    .Where(x => x.Id != pacman.Id);

            if(pacMenWhichWereNotKilledYet.Any())
            {
                return;
            }

            dataContext.AddGameEvent(EventType.GameEnded, string.Format("Game Over. Ghost {0} ate the last PacMan {1}. Ghosts win!", ghost.Name, pacman.Name), ghost.Id, ghost.GameId);

            pacman.Game.StateEnum = GameState.GameOver;
            pacman.Game.StateChangeTime = DateTime.Now;
        }
    }

    public class AddScoreIfPacManAteGhostRule : IPacManGhostCollisionRule
    {
        public const int ScoreForEatingGhost=200;

        public void DoSideEffects(Player pacman, Player ghost, PacManDataContext dataContext)
        {
            if (pacman.Game.StateEnum == GameState.SuperPacMan)
            {
                pacman.Score += ScoreForEatingGhost;
                pacman.Game.Score += ScoreForEatingGhost;
            }
        }
    }
}